package com.service.business.trading.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.service.business.base.dto.LoginUserSession;
import com.service.business.base.service.ConfigService;
import com.service.business.member.dto.MemberStoreChange;
import com.service.business.member.service.MemberJAService;
import com.service.business.member.service.MemberService;
import com.service.business.member.service.MemberStoreService;
//import com.service.business.rabbitmq.binding.MatchSendHandler;
import com.service.business.support.SessionUtil;
import com.service.business.trading.controller.rep.TradingSpotConfigRep;
import com.service.business.trading.controller.rep.TradingSpotOrderPageRep;
import com.service.business.trading.controller.req.TradingSpotCreateReq;
import com.service.business.trading.controller.req.TradingSpotPageReq;
import com.service.business.trading.service.TradingSpotOrderService;
import com.service.business.trading.service.TradingSpotPairsService;
import com.service.business.trading.service.TradingSpotTradesService;
import com.service.business.trading.vo.TradingSpotOrderVO;
import com.service.core.exception.CommonException;
import com.service.core.rest.response.CommonPageRep;
import com.service.dao.constants.ConfigConstants;
import com.service.dao.enums.MemberJAType;
import com.service.dao.model.*;
import com.service.match.common.entity.SpotOrderVo;
import com.service.match.common.entity.SpotTradeVo;
import com.service.match.common.enums.TradingSpotEnum;
import com.service.match.common.utils.TradingSpotUtils;
import com.service.utility.common.MathUtil;
import com.service.utility.common.UUIDUtil;
import com.service.utility.modelmapper.ModelMapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.service.dao.mapper.TradingSpotOrderMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service("tradingSpotOrderService")
public class TradingSpotOrderServiceImpl extends ServiceImpl<TradingSpotOrderMapper, TradingSpotOrder> implements TradingSpotOrderService {

    @Autowired
    private SessionUtil sessionUtil;
    @Autowired
    private ConfigService configService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private MemberJAService memberJAService;
//    @Autowired
//    private MatchSendHandler matchSendHandler;
    @Autowired
    private MemberStoreService memberStoreService;
    @Autowired
    private TradingSpotPairsService tradingSpotPairsService;
    @Autowired
    private TradingSpotTradesService tradingSpotTradesService;
    @Value("${tradingSpotPrefix}")
    private String tradingSpotPrefix;

    @Override
    public TradingSpotConfigRep listPairsConfig() {
        return TradingSpotConfigRep.builder()
                .pairs(tradingSpotPairsService.listPairs())
//                .config(configService.getConfig2MapByGroup(ConfigConstants.Group.trading_spot.getCode()))
                .build();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrder(TradingSpotCreateReq createReq, TradingSpotEnum.TradeType tradeType,
                            LoginUserSession session, TradingSpotPairs spotPairs) {
//        Map<String, String> config = configService.getConfig2MapByGroup(ConfigConstants.Group.trading_spot.getCode());
//        if (StringUtils.equals(config.get(ConfigConstants.TRADING_SPOT_OPEN), ConfigConstants.Value.INVALID.getCode())) {
//            throw new CommonException("币币交易暂时未开通，敬请期待", "trading_spot_exception_not_open");
//        }
        memberService.validSafetyPwd(session.getUserId(), createReq.getSafetyPwd());

        createReq.setTradeNum(MathUtil.keep4BitDecimalNormal(createReq.getTradeNum()));//处理一下小数位，4位
        if (!ObjectUtils.isEmpty(createReq.getOrderPrice())) {
            createReq.setOrderPrice(MathUtil.keep4BitDecimalNormal(createReq.getOrderPrice()));//处理下小数位，4位
        }

        if (ObjectUtils.nullSafeEquals(createReq.getPriceType(), TradingSpotEnum.PriceType.LIMIT.getCode())
                && ObjectUtils.isEmpty(createReq.getOrderPrice())) {
            throw new CommonException("价格不能为空", "trading_spot_exception_order_price_not_null");
        }

        TradingSpotOrderVO spotOrderVO = frostMemberStore(createReq, spotPairs, session, tradeType);

        TradingSpotOrder spotOrder = ModelMapperUtil.map(spotOrderVO, TradingSpotOrder.class);
        spotOrder.setSpotStatus(TradingSpotEnum.Status.CREATED.getCode());
        spotOrder.setTradeType(tradeType.getCode());
        spotOrder.setPriceType(createReq.getPriceType());
        spotOrder.setCreateTime(new Date());
        spotOrder.setDealNum(BigDecimal.ZERO);
        spotOrder.setMemberId(session.getUserId());
        spotOrder.setOrderPrice(createReq.getOrderPrice());
        spotOrder.setTradeNo(buildTradeNo());
        spotOrder.setUpdateTime(new Date());
        save(spotOrder);

        memberJAService.updateById(JournalAccount.builder().id(spotOrderVO.getJaId()).orderId(spotOrder.getId()).build());

        //TODO:创建币币交易成功，发送MQ
//        matchSendHandler.sendNewOrder(buildMsgVo(spotOrder, tradeType));
    }

    public SpotOrderVo buildMsgVo(TradingSpotOrder spotOrder, TradingSpotEnum.TradeType tradeType) {
        return buildMsgVo(spotOrder, tradeType.getCode());
    }

    @Override
    public SpotOrderVo buildMsgVo(TradingSpotOrder spotOrder, Integer tradeType) {
        SpotOrderVo msgVo = ModelMapperUtil.map(spotOrder, SpotOrderVo.class);
        msgVo.setFinishNumber(BigDecimal.ZERO);
        msgVo.setSpotState(spotOrder.getSpotStatus());
        msgVo.setSurplusFrozen(spotOrder.getSurplusFrozen());
        if (TradingSpotUtils.isBuy(tradeType)) {
            if (!TradingSpotUtils.isMarket(spotOrder.getPriceType())) {
                msgVo.setUnFinishNumber(spotOrder.getTradeNum());
            }
        } else {
            msgVo.setUnFinishNumber(spotOrder.getTradeNum());
        }
        return msgVo;
    }

    private String buildTradeNo() {
        String no = tradingSpotPrefix + DateFormatUtils.format(new Date(), "yyyyMMdd") + UUIDUtil.randomUUID10().substring(0, 8);
        TradingSpotOrder otcOrder = getOne(new QueryWrapper<TradingSpotOrder>()
                .lambda().eq(TradingSpotOrder::getTradeNo, no));
        if (!ObjectUtils.isEmpty(otcOrder)) {
            no = buildTradeNo();
        }
        return no;
    }

    private TradingSpotOrderVO frostMemberStore(TradingSpotCreateReq createReq, TradingSpotPairs spotPairs,
                                                LoginUserSession session, TradingSpotEnum.TradeType tradeType) {

        String coinName;
        BigDecimal frostNum;
        TradingSpotOrderVO spotOrder = ModelMapperUtil.map(spotPairs, TradingSpotOrderVO.class);
        if (TradingSpotUtils.isBuy(tradeType.getCode())) {
            coinName = spotPairs.getTradeCoinsName();
            if (TradingSpotUtils.isMarket(createReq.getPriceType())) {
                frostNum = createReq.getTradeNum();
                spotOrder.setTotalMoney(createReq.getTradeNum());
                spotOrder.setTradeNum(BigDecimal.ZERO);
            } else {
                spotOrder.setTotalMoney(createReq.getTradeNum().multiply(createReq.getOrderPrice()));
                frostNum = spotOrder.getTotalMoney();
                spotOrder.setTradeNum(createReq.getTradeNum());
            }
        } else {
            coinName = spotPairs.getCoinsName();
            frostNum = createReq.getTradeNum();
            spotOrder.setTradeNum(createReq.getTradeNum());
            if (TradingSpotUtils.isMarket(createReq.getPriceType())) {
                spotOrder.setTotalMoney(BigDecimal.ZERO);
            } else {
                spotOrder.setTotalMoney(createReq.getTradeNum().multiply(createReq.getOrderPrice()));
            }
        }
//        frostNum = MathUtil.keep4BitDecimalNormal(frostNum);//小数位处理一下，收
//        spotOrder.setTotalMoney(MathUtil.keep4BitDecimalNormal(spotOrder.getTotalMoney()));//同步与frostNum处理一致
        spotOrder.setSurplusFrozen(frostNum);
        MemberStore memberStore = this.validMemberStore(session.getUserId(), coinName, frostNum);

        MemberStoreChange memberStoreChange = MemberStoreChange.builder()
                .changeNum(frostNum)
                .coinsId(memberStore.getCoinsId())
                .coinsName(memberStore.getCoinsName())
                .memberId(session.getUserId())
                .jaType(MemberJAType.FROST_TRADING_SPOT)
                .remark(MemberJAType.FROST_TRADING_SPOT.getMsg())
                .build();
        Integer jaId = memberStoreService.changeMemberStore(memberStoreChange);
        spotOrder.setJaId(jaId);
        return spotOrder;
    }

    public MemberStore validMemberStore(Integer memberId, String coin, BigDecimal num) {
        MemberStore memberStore = memberStoreService.getMemberStore(memberId, coin);
        if (memberStore.getNum().compareTo(num) < 0) {
            throw new CommonException("会员余额不足", "withdraw_fail_by_not_enough_num");
        }
        return memberStore;
    }

    @Override
    public CommonPageRep<TradingSpotOrderPageRep> pageSpot(TradingSpotPageReq pageReq) {
        LoginUserSession session = sessionUtil.getUser();

        Page<TradingSpotOrder> page = PageHelper.startPage(pageReq.getPageNo(), pageReq.getPageSize());
        LambdaQueryWrapper<TradingSpotOrder> queryWrapper = new QueryWrapper<TradingSpotOrder>().lambda()
                .eq(TradingSpotOrder::getMemberId, session.getUserId())
                .in(TradingSpotOrder::getSpotStatus, pageReq.getSpotStatus())
                .orderByDesc(TradingSpotOrder::getCreateTime);

        if (StringUtils.isNotBlank(pageReq.getSymbol())) {
            queryWrapper.eq(TradingSpotOrder::getSymbol, pageReq.getSymbol());
        }

        list(queryWrapper);

        return CommonPageRep.buildResultRep(page, page.getResult().stream()
                .map(item -> ModelMapperUtil.map(item, TradingSpotOrderPageRep.class))
                .collect(Collectors.toList()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendMatchEngineCallback(Integer orderId) {
        TradingSpotOrder spotOrder = getById(orderId);
        if (ObjectUtils.isEmpty(spotOrder)) {
            throw new CommonException("不存在此交易", "trading_spot_exception_order_not_exist");
        }

        if (ObjectUtils.nullSafeEquals(spotOrder.getSpotStatus(), TradingSpotEnum.Status.CREATED.getCode())) {
            updateById(TradingSpotOrder.builder()
                    .id(orderId)
                    .spotStatus(TradingSpotEnum.Status.SEND_ENGINE.getCode())
                    .build());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSpotOrder(SpotOrderVo order, TradingSpotEnum.Status status) {
        log.info("updateSpotOrder:{}, 状态:{}", order, status);
        TradingSpotOrder spotOrder = getById(order.getId());

        if (ObjectUtils.isEmpty(spotOrder)) {
            throw new CommonException("不存在此交易:" + spotOrder.getId());
        }

        TradingSpotOrder.TradingSpotOrderBuilder builder = TradingSpotOrder.builder();
        builder.id(spotOrder.getId()).spotStatus(status.getCode())
                .dealNum(order.getFinishNumber());

        if (TradingSpotUtils.isBuy(order.getTradeType())
                && TradingSpotUtils.isComplete(status.getCode()) && order.getSurplusFrozen().compareTo(BigDecimal.ZERO) > 0) {
            log.info("订单<id:{}>完全交易:{}", order.getId(), order.getSurplusFrozen());
            if(order.getSurplusFrozen().compareTo(BigDecimal.ZERO) > 0){
                MemberStoreChange payBack = MemberStoreChange.builder()
                        .memberId(order.getMemberId())
                        .orderId(order.getId())
                        .changeNum(order.getSurplusFrozen())
                        .coinsId(spotOrder.getTradeCoinsId())
                        .coinsName(spotOrder.getTradeCoinsName())
                        .jaType(MemberJAType.TRADING_SPOT_PAY_BACK)
                        .remark(MemberJAType.TRADING_SPOT_PAY_BACK.getMsg() + ":交易完全,剩余退回.")
                        .build();
                memberStoreService.changeMemberStore(payBack);
                builder.surplusFrozen(BigDecimal.ZERO);
                log.info("订单<id:{}>交易完成,退回剩余:{}{}", order.getId(), order.getSurplusFrozen(), spotOrder.getTradeCoinsName());
            }
        } else {
            builder.surplusFrozen(order.getSurplusFrozen());
        }
        updateById(builder.build());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TradingSpotTrades createdSpotTrade(SpotTradeVo spotTradeVo) {
        log.debug("createdSpotTrade:{}", spotTradeVo);

        TradingSpotTrades trade = ModelMapperUtil.map(spotTradeVo, TradingSpotTrades.class);
        trade.setTotalMoney(MathUtil.mul(trade.getTradeNum(), trade.getOrderPrice()));
        TradingSpotOrder buyOder = getById(spotTradeVo.getBuyOrderId());
        TradingSpotOrder sellOrder = getById(spotTradeVo.getSellOrderId());
        if (ObjectUtils.isEmpty(buyOder) || ObjectUtils.isEmpty(sellOrder)) {
            throw new CommonException("买单或者买单不存在");
        }
        trade.setOrderType(spotTradeVo.getTradeType());
        trade.setBuyFee(tradingSpotPairsService.computeTradeFee(buyOder, trade.getOrderPrice(), trade.getTradeNum()));
        trade.setSellFee(tradingSpotPairsService.computeTradeFee(sellOrder, trade.getOrderPrice(), trade.getTradeNum()));
        tradingSpotTradesService.save(trade);
        //并发时，因事务还未提交至数据库，所以交易对手为同一人时，需使用实时计算的会员余额
        if (ObjectUtils.nullSafeEquals(trade.getBuyMemberId(), trade.getSellMemberId())) {
            this.dealSameMemberStore(trade, buyOder, sellOrder);
        } else {
            this.dealDiffMemberStore(trade, buyOder, sellOrder);
        }
        return trade;
    }

    private void dealSameMemberStore(TradingSpotTrades trade, TradingSpotOrder buyOder, TradingSpotOrder sellOrder) {
        //释放卖方冻结的卖币
        MemberStore sellStore = memberStoreService.getMemberStore(trade.getSellMemberId(), sellOrder.getCoinsName());
        MemberStoreChange sellStoreRelease = MemberStoreChange.builder()
                .memberId(trade.getSellMemberId())
                .coinsId(sellOrder.getCoinsId())
                .coinsName(sellOrder.getCoinsName())
                .jaType(MemberJAType.FROST_TRADING_SPOT_RELEASE)
                .orderId(trade.getId())
                .changeNum(trade.getTradeNum())
                .remark("交易成功," + MemberJAType.FROST_TRADING_SPOT_RELEASE.getMsg())
                .build();
        Integer jaId = memberStoreService.changeMemberStore(sellStore, sellStoreRelease);

        //买方获得卖方释放冻结的卖币
        MemberStoreChange buyStoreGet = MemberStoreChange.builder()
                .memberId(trade.getBuyMemberId())
                .coinsId(sellOrder.getCoinsId())
                .coinsName(sellOrder.getCoinsName())
                .jaType(MemberJAType.TRADING_SPOT_TRADE_INCOME)
                .changeNum(trade.getTradeNum().subtract(trade.getBuyFee()))
                .orderId(trade.getId())
                .remark("交易成功," + MemberJAType.TRADING_SPOT_TRADE_INCOME.getMsg() + ",手续费:" + trade.getBuyFee())
                .jaId(jaId)
                .build();
        memberStoreService.changeMemberStore(sellStore, buyStoreGet);

        //买方付款
        MemberStore payStore = memberStoreService.getMemberStore(trade.getBuyMemberId(), buyOder.getTradeCoinsName());
        MemberStoreChange buyStorePay = MemberStoreChange.builder()
                .memberId(trade.getBuyMemberId())
                .coinsId(buyOder.getTradeCoinsId())
                .coinsName(buyOder.getTradeCoinsName())
                .jaType(MemberJAType.FROST_TRADING_SPOT_RELEASE)
                .changeNum(trade.getTotalMoney())
                .orderId(trade.getId())
                .remark("交易成功," + MemberJAType.FROST_TRADING_SPOT_RELEASE.getMsg())
                .build();
        jaId = memberStoreService.changeMemberStore(payStore, buyStorePay);

        //卖方收钱
        MemberStoreChange sellStoreGet = MemberStoreChange.builder()
                .memberId(trade.getSellMemberId())
                .coinsId(buyOder.getTradeCoinsId())
                .coinsName(buyOder.getTradeCoinsName())
                .jaType(MemberJAType.TRADING_SPOT_TRADE_INCOME)
                .changeNum(trade.getTotalMoney().subtract(trade.getSellFee()))
                .orderId(trade.getId())
                .remark("交易成功," + MemberJAType.TRADING_SPOT_TRADE_INCOME.getMsg() + ",手续费:" + trade.getSellFee())
                .jaId(jaId)
                .build();
        memberStoreService.changeMemberStore(payStore, sellStoreGet);
    }

    private void dealDiffMemberStore(TradingSpotTrades trade, TradingSpotOrder buyOder, TradingSpotOrder sellOrder) {
        //释放卖方冻结的卖币
        MemberStoreChange sellStoreRelease = MemberStoreChange.builder()
                .memberId(trade.getSellMemberId())
                .coinsId(sellOrder.getCoinsId())
                .coinsName(sellOrder.getCoinsName())
                .jaType(MemberJAType.FROST_TRADING_SPOT_RELEASE)
                .orderId(trade.getId())
                .changeNum(trade.getTradeNum())
                .remark("交易成功," + MemberJAType.FROST_TRADING_SPOT_RELEASE.getMsg())
                .build();
        Integer jaId = memberStoreService.changeMemberStore(sellStoreRelease);

        //买方获得卖方释放冻结的卖币
        MemberStoreChange buyStoreGet = MemberStoreChange.builder()
                .memberId(trade.getBuyMemberId())
                .coinsId(sellOrder.getCoinsId())
                .coinsName(sellOrder.getCoinsName())
                .jaType(MemberJAType.TRADING_SPOT_TRADE_INCOME)
                .changeNum(trade.getTradeNum().subtract(trade.getBuyFee()))
                .orderId(trade.getId())
                .remark("交易成功," + MemberJAType.TRADING_SPOT_TRADE_INCOME.getMsg() + ",手续费:" + trade.getBuyFee())
                .jaId(jaId)
                .build();
        memberStoreService.changeMemberStore(buyStoreGet);

        //买方付款
        MemberStoreChange buyStorePay = MemberStoreChange.builder()
                .memberId(trade.getBuyMemberId())
                .coinsId(buyOder.getTradeCoinsId())
                .coinsName(buyOder.getTradeCoinsName())
                .jaType(MemberJAType.FROST_TRADING_SPOT_RELEASE)
                .changeNum(trade.getTotalMoney())
                .orderId(trade.getId())
                .remark("交易成功," + MemberJAType.FROST_TRADING_SPOT_RELEASE.getMsg())
                .build();
        jaId = memberStoreService.changeMemberStore(buyStorePay);

        //卖方收钱
        MemberStoreChange sellStoreGet = MemberStoreChange.builder()
                .memberId(trade.getSellMemberId())
                .coinsId(buyOder.getTradeCoinsId())
                .coinsName(buyOder.getTradeCoinsName())
                .jaType(MemberJAType.TRADING_SPOT_TRADE_INCOME)
                .changeNum(trade.getTotalMoney().subtract(trade.getSellFee()))
                .orderId(trade.getId())
                .remark("交易成功," + MemberJAType.TRADING_SPOT_TRADE_INCOME.getMsg() + ",手续费:" + trade.getSellFee())
                .jaId(jaId)
                .build();
        memberStoreService.changeMemberStore(sellStoreGet);
    }


    @Override
    public void applyCancelSpotOrder(String tradeNo) {
        if (!configService.configValueIsValid(ConfigConstants.TRADING_SPOT_OPEN)) {
            throw new CommonException("币币交易暂时未开通，敬请期待", "trading_spot_exception_not_open");
        }
        LoginUserSession session = sessionUtil.getUser();
        if(session.getStoreFreezeStatus() == com.service.dao.enums.MemberEnums.StoreStatus.FROZEN.getCode()){
            throw new CommonException("账户资产已冻结，如有疑问请联系客服","account_assets_frozen");
        }
        TradingSpotOrder spotOrder = getSpotOrderByNo(tradeNo, session.getUserId());

        if (ObjectUtils.nullSafeEquals(spotOrder.getSpotStatus(), TradingSpotEnum.Status.COMPLETED.getCode())) {
            throw new CommonException("撤销失败，该交易已完成", "trading_spot_cancel_exception_order_has_completed");
        }
        if (ObjectUtils.nullSafeEquals(spotOrder.getSpotStatus(), TradingSpotEnum.Status.CANCEL.getCode())) {
            throw new CommonException("撤销失败，该交易已撤销", "trading_spot_cancel_exception_order_has_cancel");
        }
        //todo:发送至撮合引擎，从引擎测消交易
//        matchSendHandler.sendCancelOrder(buildMsgVo(spotOrder, TradingSpotEnum.TradeType.of(spotOrder.getTradeType())
//                .orElseThrow(() -> new CommonException("不存在此交易", "trading_spot_exception_order_not_exist"))));

    }

    @Override
    public TradingSpotOrder getSpotOrderByNo(String tradeNo, Integer memberId) {
        TradingSpotOrder result = getOne(new QueryWrapper<TradingSpotOrder>().lambda()
                .eq(TradingSpotOrder::getTradeNo, tradeNo)
                .eq(TradingSpotOrder::getMemberId, memberId).last("limit 1"));
        if (ObjectUtils.isEmpty(result)) {
            throw new CommonException("不存在此交易", "trading_spot_exception_order_not_exist");
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelSpotOrder(SpotOrderVo spotOrderVo) {
        log.debug("交易撤销:{}", spotOrderVo);
        TradingSpotOrder spotOrder = getById(spotOrderVo.getId());
        if (ObjectUtils.isEmpty(spotOrder)) {
            throw new CommonException("不存在此交易", "trading_spot_exception_order_not_exist");
        }

        if (ObjectUtils.nullSafeEquals(spotOrder.getSpotStatus(), TradingSpotEnum.Status.COMPLETED.getCode())) {
            log.info("撤销订单<{}>失败，该订单已完成", spotOrder);
            return;
        }
        if (ObjectUtils.nullSafeEquals(spotOrder.getSpotStatus(), TradingSpotEnum.Status.CANCEL.getCode())) {
            log.info("撤销订单<{}>失败，该订单已撤销", spotOrder);
            return;
        }

        BigDecimal backNum = spotOrderVo.getSurplusFrozen();
        if(backNum.compareTo(BigDecimal.ZERO) > 0){
            String coinName = TradingSpotUtils.isBuy(spotOrder.getTradeType()) ? spotOrder.getTradeCoinsName() : spotOrder.getCoinsName();
            MemberStoreChange memberStoreChange = MemberStoreChange.builder()
                    .memberId(spotOrderVo.getMemberId())
                    .jaType(MemberJAType.TRADING_SPOT_TRADE_CANCEL)
                    .changeNum(backNum)
                    .coinsName(coinName)
                    .orderId(spotOrder.getId())
                    .remark(MemberJAType.TRADING_SPOT_TRADE_CANCEL.getMsg())
                    .build();

            memberStoreService.changeMemberStore(memberStoreChange);
        }
        updateById(TradingSpotOrder.builder()
                .id(spotOrder.getId())
                .surplusFrozen(BigDecimal.ZERO)
                .dealNum(spotOrderVo.getFinishNumber())
                .spotStatus(TradingSpotEnum.Status.CANCEL.getCode())
                .build());
    }

    @Override
    public List<TradingSpotOrder> listByStatusAndTime(TradingSpotEnum.Status status, Date time) {
        return list(new QueryWrapper<TradingSpotOrder>().lambda()
                .eq(TradingSpotOrder::getSpotStatus, status.getCode())
                .le(TradingSpotOrder::getCreateTime, time));
    }
}
